home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Select (Limited Edition)
/
Computer Select.iso
/
pcmag
/
v11n09
/
drum1.exe
/
DRUMC.EXE
/
DRUM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-13
|
20KB
|
564 lines
/*----------------------------------------------------
DRUM.C -- MIDI Drum Machine for Multimedia Windows
(c) Charles Petzold, 1992
----------------------------------------------------*/
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "drum.h"
#include "drumdll.h"
#include "drumfile.h"
typedef unsigned int UINT ;
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
long FAR PASCAL _export WndProc (HWND, UINT, UINT, LONG) ;
BOOL FAR PASCAL _export AboutProc (HWND, UINT, UINT, LONG) ;
void DrawRectangle (HDC, int, int, DWORD *, DWORD *) ;
void ErrorMessage (HWND, char *, LPSTR) ;
void DoCaption (HWND, char *) ;
short AskAboutSave (HWND, char *) ;
char *szPerc [NUM_PERC] =
{
"Acoustic Bass Drum", "Bass Drum 1", "Side Stick",
"Acoustic Snare", "Hand Clap", "Electric Snare",
"Low Floor Tom", "Closed High-Hat", "High Floor Tom",
"Pedal High Hat", "Low Tom", "Open High Hat",
"Low-Mid Tom", "High-Mid Tom", "Crash Cymbal 1",
"High Tom", "Ride Cymbal 1", "Chinese Cymbal",
"Ride Bell", "Tambourine", "Splash Cymbal",
"Cowbell", "Crash Cymbal 2", "Vibraslap",
"Ride Cymbal 2", "High Bongo", "Low Bongo",
"Mute High Conga", "Open High Conga", "Low Conga",
"High Timbale", "Low Timbale", "High Agogo",
"Low Agogo", "Cabasa", "Maracas",
"Short Whistle", "Long Whistle", "Short Guiro",
"Long Guiro", "Claves", "High Wood Block",
"Low Wood Block", "Mute Cuica", "Open Cuica",
"Mute Triangle", "Open Triangle"
} ;
char szAppName [] = "Drum" ;
char szUntitled [] = "(Untitled)" ;
char szBuffer [80 + _MAX_FNAME + _MAX_EXT] ;
HANDLE hInst ;
short cxChar, cyChar ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
if (hPrevInstance)
{
ErrorMessage (NULL, "Only one instance is allowed!", NULL) ;
return 0 ;
}
hInst = hInstance ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
hwnd = CreateWindow (szAppName, NULL,
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, lpszCmdParam) ;
ShowWindow (hwnd, SW_SHOWMAXIMIZED) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
long FAR PASCAL _export WndProc (HWND hwnd, UINT message, UINT wParam,
LONG lParam)
{
static BOOL bNeedSave ;
static char szFileName [_MAX_PATH],
szTitleName [_MAX_FNAME + _MAX_EXT] ;
static DRUM drum ;
static FARPROC lpfnAboutProc ;
static HMENU hMenu ;
static int iTempo = 50, iIndexLast ;
char * szError ;
DWORD dwCurrPos ;
HDC hdc ;
int i, x, y ;
PAINTSTRUCT ps ;
switch (message)
{
case WM_CREATE:
// Initialize DRUM structure
drum.iMsecPerBeat = 100 ;
drum.iVelocity = 64 ;
drum.iNumBeats = 32 ;
DrumSetParams (&drum) ;
// Other initialization
cxChar = LOWORD (GetDialogBaseUnits ()) ;
cyChar = HIWORD (GetDialogBaseUnits ()) ;
lpfnAboutProc = MakeProcInstance ((FARPROC) AboutProc, hInst) ;
hMenu = GetMenu (hwnd) ;
// Process command line and start sequence
lstrcpy (szFileName,
((LPCREATESTRUCT) lParam)->lpCreateParams) ;
if (lstrlen (szFileName))
{
if (DrumFileParse (szFileName, szTitleName))
{
szError = DrumFileRead (&drum, szFileName) ;
if (szError == NULL)
{
iTempo = (int) (50 *
(log10 (drum.iMsecPerBeat) - 1)) ;
DrumSetParams (&drum) ;
}
else
{
ErrorMessage (hwnd, szError, szTitleName) ;
szTitleName [0] = '\0' ;
}
}
else
{
ErrorMessage (hwnd, "Invalid command line: %s",
((LPCREATESTRUCT) lParam)->lpCreateParams) ;
szTitleName [0] = '\0' ;
}
}
// Initialize "Volume" scroll bar
SetScrollRange (hwnd, SB_HORZ, 1, 127, FALSE) ;
SetScrollPos (hwnd, SB_HORZ, drum.iVelocity, TRUE) ;
// Initialize "Tempo" scroll bar
SetScrollRange (hwnd, SB_VERT, 0, 100, FALSE) ;
SetScrollPos (hwnd, SB_VERT, iTempo, TRUE) ;
DoCaption (hwnd, szTitleName) ;
return 0 ;
case WM_COMMAND:
switch (wParam)
{
case IDM_NEW:
if (bNeedSave && IDCANCEL ==
AskAboutSave (hwnd, szTitleName))
return 0 ;
// Clear drum pattern
for (i = 0 ; i < NUM_PERC ; i++)
{
drum.dwSeqBas [i] = 0L ;
drum.dwSeqExt [i] = 0L ;
}
InvalidateRect (hwnd, NULL, FALSE) ;
DrumSetParams (&drum) ;
bNeedSave = FALSE ;
return 0 ;
case IDM_OPEN:
// Save previous file
if (bNeedSave && IDCANCEL ==
AskAboutSave (hwnd, szTitleName))
return 0 ;
// Open the selected file
if (DrumFileOpenDlg (hwnd, szFileName, szTitleName))
{
szError = DrumFileRead (&drum, szFileName) ;
if (szError != NULL)
{
ErrorMessage (hwnd, szError, szTitleName) ;
szTitleName [0] = '\0' ;
}
else
{
// Set new parameters
iTempo = (int) (50 *
(log10 (drum.iMsecPerBea